package com.dzpk.gameserver.util;

import com.dzpk.gameserver.module.player.Player;
import com.dzpk.gameserver.module.player.PlayerControler;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 广播管理器
 * <p/>
 * By Gamer 2013
 */
public class Broadcaster {

    public static void broadcast(IoSession session, Object message) {
        if (session != null) {
            if ((message instanceof IoBuffer)) {
                IoBuffer tmp = (IoBuffer) message;
                if (tmp.hasRemaining()) {
                    session.write(tmp.duplicate());
                }
            } else {
                session.write(message);
                if (log.isDebugEnabled()) {
                    log.debug(String.format("broadcast %s to session(%s)", message.toString(), session.getId()));
                }
            }
        }
    }

    public static void broadcast(Collection<Long> sessionIds, Object message) {
        for (Long sid : sessionIds) {
            broadcast(BeanControler.getGameServer().getSession(sid), message);
        }
    }

    public static void broadcast(Collection<Player> players, IoBuffer ioBuffer) {
        for (Player player : players) {
            broadcast(player.getSession(), ioBuffer);
        }
    }

    public static void broadcastPlayerAll(final Player player, final IoBuffer message, final boolean exceptPlayer) {

        BeanControler.getAsynThreadControler().execute(new Runnable() {

            @Override
            public void run() {
                Collection<Player> onlinePlayers = PlayerControler.getInstance().getOnlinePlayers();

                for (Player p : onlinePlayers) {
                    try {
                        if (exceptPlayer && p.getPlayerId() == player.getPlayerId()) {
                            continue;
                        }

                        broadcast(p.getSession(), message);
                    } catch (RuntimeException e) {
                        log.error("", e);
                    }
                }
            }

        });
    }

    public static void broadcastPlayerAll(IoBuffer message) {
        broadcastPlayerAll(null, message, false);
    }


    public static void broadcastByPlayerId(Collection<Long> playerIds, Collection<Long> exceptPlayerIds, Object message) {
        Set<Long> tmp = new HashSet<Long>(playerIds);

        if (exceptPlayerIds != null && exceptPlayerIds.size() > 0) {
            tmp.removeAll(exceptPlayerIds);
        }

        Set<Long> sessionIds = new HashSet<Long>(0);

        for (Long pid : tmp) {
            // 如果玩家不在线则不进行广播
            Long sid = PlayerControler.getInstance().getSessionId(pid);
            if (null != sid) {
                sessionIds.add(sid);
            }
        }

        tmp.clear();
        tmp = null;

        broadcast(sessionIds, null, message);
    }

    public static void broadcastByPlayerId(Collection<Long> playerIds, Object message) {
        broadcastByPlayerId(playerIds, null, message);
    }


    private final static Logger log = LoggerFactory.getLogger(Broadcaster.class);


    public static void broadcast(Collection<Long> sessionIds, Collection<Long> exceptSessionIds, Object message) {
        if (exceptSessionIds != null) {
            sessionIds.removeAll(exceptSessionIds);
        }

        broadcast(sessionIds, message);
    }

}
